//头文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <mysql/mysql.h>
#include "cJSON.h"

#define LOCAL_IP  "192.168.10.8"
#define LOCAL_PORT 6666 

#define REMOTE_IP  "192.168.10.8"
#define REMOTE_PORT 7777

typedef struct employee{
	char login[20];
	char type[20];
	char name[20];
	char meeting[100];
	char content[100];
	char start_time[16];
	char end_time[16];
	char place[100];
	char participants[100];
	char message[100];
}EMP;

struct sockaddr_in saddr;

/*函数声明*/
EMP *parseJson(char *p);//解主管发过来的日志信息包
int insert_supervisor(EMP *stu, MYSQL mysql);//主管数据插入到数据库
int insert_employee(EMP *stu, MYSQL mysql);//员工数据插入到数据库
int delete_supervisor(EMP *stu, MYSQL mysql);//在数据库中删除主管数据
int delete_employee(EMP *stu, MYSQL mysql);//在数据库中删除员工数据
int update_employee(EMP *stu, MYSQL mysql);//审批员工的日程信息
void show_supervisor(EMP *stu, MYSQL mysql,int client_buf);//输入主管姓名将信息返回客户端
void show_employee(EMP *stu, MYSQL mysql,int client_buf);//输入员工姓名将信息返回客户端

int main(int argc,const char* argv[]){
	MYSQL mysql;
	MYSQL *flag = NULL;
	//初始化
    mysql_init(&mysql);
	//连接数据库
    flag = mysql_real_connect(&mysql,"localhost","root","20000418","LOG_management",0,NULL,0);
	if(flag == NULL)
    {
        printf("连接数据库错误:%s\n",mysql_error(&mysql));
        exit(1);
    }

	int sc = socket(AF_INET,SOCK_STREAM,0);
	if(sc == -1)
	{
		perror("socket");
		return -1;
	}
	
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(LOCAL_PORT);
	saddr.sin_addr.s_addr = inet_addr(LOCAL_IP);
	
	int optval = 1;
	//bind 的地址允许重复使用
	//设置sock状态
	setsockopt(sc,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));
	
	int ret = bind(sc,(struct sockaddr*)&saddr,sizeof(saddr));
	if(ret == -1)
	{
		perror("bind");
		return -1;
	}
	//启动监听
	int listen_is = listen(sc,10);
	if(listen_is == -1)
	{
		perror("listen");
		exit(1);
	}
	printf("监听已启动");
	
	struct sockaddr_in peer_addr;
	int peer_len = sizeof(peer_addr);
	
	char recv_buf[1000]	 = {0};
	EMP *stu;
	char *p = NULL;
	p = (char*)malloc(1000);
	MYSQL desc;
	//连接并接收数据包
	int client_buf = accept(sc,(struct sockaddr*)&peer_addr,&peer_len);
	printf("连接已经建立\n");
		
	while(1){
		memset(p,0,1000);
		memset(&peer_addr,0,sizeof(peer_addr));
		//读取数据至p字符串
		int re = read(client_buf,p,1000);
		stu = parseJson(p);

		
		//根据主管标志进入主管操作
		if(strcmp(stu->login, "supervisor") == 0){
		while(1){
			memset(p, 0,sizeof(p));
			read(client_buf,p,1000);
			stu = parseJson(p);
			//根据创建标志进行增加操作
			if(strcmp(stu->type,"creat") == 0){
				int flag = insert_supervisor(stu,mysql);
				if(flag == 0){
					printf("创建失败\n");
				}
			}
			//根据删除标志进行删除操作
			if(strcmp(stu->type,"delete") == 0){
				int flag = delete_supervisor(stu,mysql);
				if(flag == 0){
					printf("删除失败\n");
				}
			}
			//根据修改标志进行修改操作
			if(strcmp(stu->type,"change") == 0){
				int flag = delete_supervisor(stu,mysql);
				if(flag == 0){
					printf("删除失败\n");
				}
				int temp = insert_supervisor(stu,mysql);	
			}
			//根据审批标志进行审批操作
			if(strcmp(stu->type,"approval") == 0){
				int flag = update_employee(stu,mysql);
				if(flag == 0){
					printf("审批失败\n");
				}
			}
			//根据查找标志进行查找操作
			if(strcmp(stu->type,"check") == 0){
				show_supervisor(stu,mysql,client_buf);				
			}
		}
	}
	
		//根据员工标志进行员工操作
		if(strcmp(stu->login, "employee") == 0){
			while(1){
				memset(p, 0,sizeof(p));
				read(client_buf,p,1000);
				stu = parseJson(p);
				//根据创建标志进行增加操作
				if(strcmp(stu->type,"creat") == 0){
					int flag = insert_employee(stu, mysql);
					if(flag == 0){
						printf("创建失败\n");
					}
				}
				//根据删除标志进行删除操作
				if(strcmp(stu->type,"delete") == 0){
					int flag = delete_employee(stu, mysql);
					if(flag == 0){
						printf("删除失败\n");
					}
				}
				//根据修改标志进行修改操作
				if(strcmp(stu->type,"change") == 0){
					int flag = delete_employee(stu, mysql);
					if(flag == 0){
						printf("删除失败\n");
					}
					int temp = insert_employee(stu, mysql);
					if(temp == 0){
						printf("创建失败\n");
					}	
				}
				//根据查找标志进行查找操作
				if(strcmp(stu->type,"check") == 0){
					show_employee(stu, mysql,client_buf);					
				}
			}
		}
	}
	close(sc);
	return 0;
}

/*
函数功能：解主管发过来的日志信息包
参数：char *p
返回值:EMP *stu
*/
EMP *parseJson(char *p){
	EMP *stu = NULL;
	stu = (EMP*)malloc(sizeof(EMP));
	memset(stu, 0, sizeof(EMP));
	
    cJSON* root = cJSON_Parse(p);
    
	cJSON* login = cJSON_GetObjectItem(root, "login");
	cJSON* type = cJSON_GetObjectItem(root, "type");
	cJSON* name = cJSON_GetObjectItem(root, "name");
	cJSON* meeting = cJSON_GetObjectItem(root, "meeting");
    cJSON* content = cJSON_GetObjectItem(root, "content");
    cJSON* start_time = cJSON_GetObjectItem(root, "start_time");
	cJSON* end_time = cJSON_GetObjectItem(root, "end_time");
	cJSON* place = cJSON_GetObjectItem(root, "place");
	cJSON* participants = cJSON_GetObjectItem(root, "participants");
	cJSON* message = cJSON_GetObjectItem(root, "message");

    char* lo = cJSON_GetStringValue(login);
	char* ty = cJSON_GetStringValue(type);
	char* na = cJSON_GetStringValue(name);
	char* me = cJSON_GetStringValue(meeting);
    char* co = cJSON_GetStringValue(content);
	char* st = cJSON_GetStringValue(start_time);
	char* en = cJSON_GetStringValue(end_time);
	char* pl = cJSON_GetStringValue(place);
	char* pa = cJSON_GetStringValue(participants);
	char* mes = cJSON_GetStringValue(message);
	
	strcpy(stu->login,lo);
	strcpy(stu->type,ty);
	strcpy(stu->name,na);
	strcpy(stu->meeting,me);
	strcpy(stu->content,co);
	strcpy(stu->start_time,st);
	strcpy(stu->end_time,en);
	strcpy(stu->place,pl);
	strcpy(stu->participants,pa);
	strcpy(stu->message,mes);
    
    cJSON_Delete(root);
	return stu;
}

/*
函数功能：将主管解出的日志信息存到数据库中
参数：EMP *stu, MYSQL mysql
返回值:int
*/
int insert_supervisor(EMP *stu, MYSQL mysql){
	int flag = 0; 
	char bufsql[1000] = {0};
	memset(bufsql, 0, sizeof(bufsql));
	sprintf(bufsql,"insert into Manage_departmental_log_information (name,meeting,content,start_time,end_time,place,participants,message) values('%s','%s','%s','%s','%s','%s','%s','%s')", stu->name,stu->meeting, stu->content, stu->start_time,stu->end_time,stu->place,stu->participants,stu->message);	
	if(mysql_query(&mysql,bufsql) != 0)
	{
		printf("%s\n",mysql_error(&mysql));
		flag = 0;
		exit(1);
	}
	flag = 1;
	printf("\t\t%p\n",&mysql);
	return flag;
}

/*
函数功能：将员工解出的日志信息存到数据库中
参数：EMP *stu, MYSQL mysql
返回值:int
*/
int insert_employee(EMP *stu, MYSQL mysql){
	int flag = 0; 
	char bufsql[1000] = {0};
	memset(bufsql, 0, sizeof(bufsql));
	sprintf(bufsql,"insert into Employee_log_information (name,meeting,content,start_time,end_time,place,participants,message) values('%s','%s','%s','%s','%s','%s','%s','%s')", stu->name,stu->meeting, stu->content, stu->start_time,stu->end_time,stu->place,stu->participants,stu->message);	
	if(mysql_query(&mysql,bufsql) != 0)
	{
		printf("%s\n",mysql_error(&mysql));
		flag = 0;
		exit(1);
	}
	flag = 1;
	return flag;
}

/*
函数功能：将主管解出的日志信息在数据库中删除
参数：EMP *stu, MYSQL mysql
返回值:int
*/
int delete_supervisor(EMP *stu, MYSQL mysql){
	int flag = 0;
	char bufsql[1000] = {0};
	memset(bufsql, 0, sizeof(bufsql));
	sprintf(bufsql,"delete from Manage_departmental_log_information where name = '%s' and meeting = '%s'", stu->name,stu->meeting);	
	if(mysql_query(&mysql,bufsql) != 0)
	{
		printf("%s\n",mysql_error(&mysql));
		flag = 0;
		exit(1);
	}
	flag = 1;
	printf("\t\t%p\n",&mysql);
	return 1;
}

/*
函数功能：将员工解出的日志信息在数据库中删除
参数：EMP *stu, MYSQL mysql
返回值:int
*/
int delete_employee(EMP *stu, MYSQL mysql){
	int flag = 0;
	char bufsql[1000] = {0};
	memset(bufsql, 0, sizeof(bufsql));
	sprintf(bufsql,"delete from Employee_log_information where name = '%s' and meeting = '%s'", stu->name,stu->meeting);	
	if(mysql_query(&mysql,bufsql) != 0)
	{
		printf("%s\n",mysql_error(&mysql));
		flag = 0;
		exit(1);
	}
	flag = 1;
	printf("\t\t%p\n",&mysql);
	return 1;
}

/*
函数功能：将主管解出的日志信息将员工的数据库中的message替换
参数：EMP *stu, MYSQL mysql
返回值:int
*/
int update_employee(EMP *stu, MYSQL mysql){
	int flag = 0;
	char bufsql[1000] = {0};
	memset(bufsql, 0, sizeof(bufsql));
	if(strcmp(stu->type,"agree") == 0){
		sprintf(bufsql,"update Employee_log_information set  messgae = 'agree' where name = '%s' and meeting = '%s'", stu->name,stu->meeting);
	}else if(strcmp(stu->type,"disagree") == 0){
		sprintf(bufsql,"update Employee_log_information set  messgae = 'disagree' where name = '%s' and meeting = '%s'", stu->name,stu->meeting);
	}		
	if(mysql_query(&mysql,bufsql) != 0)
	{
		printf("%s\n",mysql_error(&mysql));
		flag = 0;
		exit(1);
	}
	flag = 1;
	printf("\t\t%p\n",&mysql);
	return 1;
}

/*
函数功能：将主管数据库中的通过名字查询到的结果集，通过字符串发送给客户端
参数：EMP *stu, MYSQL mysql,int client_buf
返回值:void
*/
void show_supervisor(EMP *stu, MYSQL mysql,int client_buf){
	char reply[1000] = {0};
	char bufsql[1000] = {0};
	MYSQL_RES *res = NULL;
	MYSQL_ROW row;
	MYSQL_FIELD *field = NULL;
	int i = 0;
	int j = 0;
	
	sprintf(bufsql,"select *from Manage_departmental_log_information where name = '%s'",stu->name);	
	if(mysql_query(&mysql,bufsql) != 0)
	{
		printf("%s\n",mysql_error(&mysql));
		exit(1);
	}
	//显示查询结果
    //获得结果集
	res = mysql_store_result(&mysql);
	//结果集的字段信息
	field = mysql_fetch_fields(res);
	//遍历行/记录
	my_ulonglong Row = mysql_num_rows(res);
	//遍历列/字段个数
    int col = mysql_num_fields(res);
	
	for(i = 0; i < Row; i++){
		row = mysql_fetch_row(res);
		memset(reply,0,sizeof(reply));
		for(j = 0; j < col - 1; j++){
			if(row[j]!=NULL)
			{
				strcat(reply,row[j]);
				printf("%s\t", row[j]);
			}
			puts(" ");
		}
		printf("\n");
		strcat(reply,"\n");
		write(client_buf,reply,strlen(reply));
	}
}

/*
函数功能：将员工数据库中的通过名字查询到的结果集，通过字符串发送给客户端
参数：EMP *stu, MYSQL mysql,int client_buf
返回值:void
*/
void show_employee(EMP *stu, MYSQL mysql,int client_buf){
	char reply2[1000] = {0};
	char bufsql[1000] = {0};
	MYSQL_RES *res = NULL;
	MYSQL_ROW row;
	MYSQL_FIELD *field = NULL;
	int i = 0;
	int j = 0;
	
	sprintf(bufsql,"select *from Employee_log_information where name = '%s'",stu->name);	
	if(mysql_query(&mysql,bufsql) != 0)
	{
		printf("%s\n",mysql_error(&mysql));
		exit(1);
	}
	//显示查询结果
    //获得结果集
	res = mysql_store_result(&mysql);
	//结果集的字段信息
	field = mysql_fetch_fields(res);
	//遍历行/记录
	my_ulonglong Row = mysql_num_rows(res);
	//遍历列/字段个数
    int col = mysql_num_fields(res);
	
	for(i = 0; i < Row; i++){
		row = mysql_fetch_row(res);
		memset(reply2,0,sizeof(reply2));
		for(j = 0; j < col; j++){
			if(row[j]!=NULL)
			{
				strcat(reply2,row[j]);
				printf("%s\t", row[j]);
			}
			puts(" ");
		}
		printf("\n");
		strcat(reply2,"\n");
		write(client_buf,reply2,strlen(reply2));
	}
}


